package be.groept.ace.enquete.filters;

import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import be.groept.ace.enquete.model.beans.User;

/**
 * Servlet Filter implementation class PermissionFilter
 */
public class PermissionFilter implements Filter {
	private static Logger logger = Logger.getLogger(PermissionFilter.class);
	private ArrayList<String> adminUrls;
	private ArrayList<String> userUrls;
	
	public void init(FilterConfig fConfig) throws ServletException {
		
		String adminUrlString = fConfig.getInitParameter("AdminUrls");
		StringTokenizer token = new StringTokenizer(adminUrlString, ",");
		adminUrls = new ArrayList<String>();
		while (token.hasMoreTokens()) {
			adminUrls.add(token.nextToken());
		}
		
		String userUrlString = fConfig.getInitParameter("UserUrls");
		token = new StringTokenizer(userUrlString, ",");
		userUrls = new ArrayList<String>();
		while (token.hasMoreTokens()) {
			userUrls.add(token.nextToken());
		}
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		logger.debug("Entered Permission filter");
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		
		HttpSession session = httpRequest.getSession();

		String requestedUrl = httpRequest.getServletPath();
		
		User user = (User) session.getAttribute("user");
		if (listContainsUrl(adminUrls, requestedUrl) ||  listContainsUrl(userUrls, requestedUrl)) {
			
			if(user == null) {
				logger.error("User attribute has to be set in the session. Check the filter orderening and url-patterns for inconsistencies");
				throw new ServletException("User attribute has to be set in the session. Check the filter orderening and url-patterns for inconsistencies");
			}
			
			if (!listContainsUrl((user.isAdministrator() ? adminUrls : userUrls), requestedUrl)) {
				logger.error(String.format("User %s is not allowed to access page: %s", user, requestedUrl));
				httpResponse.sendError(403);
				return;
			}
			logger.debug(String.format("User %s (admin: %b) is allowed to access page: %s", user, user.isAdministrator(), requestedUrl));
		} else if (requestedUrl.equals("/") && user != null){
			//redirect to the correct home page
			requestedUrl = user.isAdministrator() ? "admin" : "user";
			logger.debug(String.format("User %s (admin: %b) is redirected to page: %s", user, user.isAdministrator(), requestedUrl));
			httpResponse.sendRedirect(httpResponse.encodeRedirectURL(requestedUrl));
			return;
		} else {
			logger.debug("Pass through the Permission filter");
		}
		
		chain.doFilter(request, response);
	}

	public void destroy() {
		adminUrls = null;
		userUrls = null;
	}
	
	private boolean listContainsUrl(ArrayList<String> list, String url) {
		boolean contains = false;
		String str = "";
		for (int i = 0; i < list.size(); i++) {
			str = list.get(i);
			if(url.startsWith(str)) {
				contains = true;
				break;
			}
		}
		return contains;
	}

}
